bitkeeper revision 1.179 (3e9e9d6686NgD7eyGZqkrhBZ7IgkDw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 17 Apr 2003 12:26:14 +0000 (12:26 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Thu, 17 Apr 2003 12:26:14 +0000 (12:26 +0000)
sched.h, schedule.c, domain.c, dom0_ops.c, dom_builder.c:
  Fixed domain death so we can now kill domains that were never actually launched.

tools/domain_builder/dom_builder.c
xen/common/dom0_ops.c
xen/common/domain.c
xen/common/schedule.c
xen/include/xeno/sched.h

index d2ba7db2c7b5174e7819451903344618dd55bfb8..13ee8d8735cad3556e928763accbe5444d3c507a 100644 (file)
@@ -43,6 +43,30 @@ static void dbstatus(char * msg)
     printf("Domain Builder: %s\n", msg);
 }
 
+static int do_kill_domain(int dom_id, int force)
+{
+    char cmd_path[MAX_PATH];
+    dom0_op_t dop;
+    int cmd_fd;
+
+    dop.cmd = DOM0_KILLDOMAIN;
+    dop.u.killdomain.domain = dom_id;
+    dop.u.killdomain.force  = force;
+
+    /* open the /proc command interface */
+    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
+    cmd_fd = open(cmd_path, O_WRONLY);
+    if(cmd_fd < 0){
+        perror(PERR_STRING);
+        return -1;
+    }
+
+    write(cmd_fd, &dop, sizeof(dom0_op_t));
+    close(cmd_fd);
+
+    return 0;
+}
+
 /* clean up domain's memory allocations */
 static void dom_mem_cleanup(dom_mem_t * dom_mem)
 {
@@ -162,7 +186,7 @@ static dom0_newdomain_t * create_new_domain(long req_mem)
 
     sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", 
         PROC_DOM_DATA);
-    while((id_fd = open(dom_id_path, O_RDONLY)) < 0){}
+    while((id_fd = open(dom_id_path, O_RDONLY)) < 0) continue;
     dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t));
     read(id_fd, dom_data, sizeof(dom0_newdomain_t));
     close(id_fd);
@@ -445,20 +469,18 @@ int main(int argc, char **argv)
     if(argc < 4) {
         dberr("Usage: dom_builder <kbytes_mem> <image> <num_vifs> "
              "[<initrd=initrd_name>] <boot_params>\n");
-        goto out;
+        return -1;
     }
 
     /* create new domain and set up all the neccessary mappings */
 
     kernel_fd = do_kernel_chcks(argv[2], atol(argv[1]), &load_addr, &ksize);
-    if(kernel_fd < 0) {
-       rc = errno; 
-        goto out;
-    }
+    if(kernel_fd < 0)
+       return -1;
     
     /* request the creation of new domain */
     if(!(dom_data = create_new_domain(atol(argv[1])))) 
-        goto out;
+        return -1;
 
     /* map domain's memory */
     if(map_dom_mem(dom_data->pg_head, dom_data->memory_kb >> (PAGE_SHIFT-10), 
@@ -520,7 +542,13 @@ int main(int argc, char **argv)
     
 out:
     if( rc >= 0 )
-       return meminfo->domain;
+    {
+        return meminfo->domain;
+    }
     else 
-       return rc;
+    {
+        if ( dom_data->domain != 0 )
+            do_kill_domain(dom_data->domain, 1);
+        return rc;
+    }
 }
index 6344254a3eb2ae14d34bfbbd05f441efc63b1bfd..d803c8e5ca6e15ed55881fb5eb7ed7788e57e5f3 100644 (file)
@@ -65,11 +65,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     {
         struct task_struct * p = find_domain_by_id(op.u.meminfo.domain);
         if ( (ret = final_setup_guestos(p, &op.u.meminfo)) != 0 )
-        {
-            p->state = TASK_DYING;
-            release_task(p);
             break;
-        }
         wake_up(p);
         reschedule(p);
         ret = p->domain;
@@ -83,13 +79,21 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         static unsigned int pro = 0;
         unsigned int dom = get_domnr();
         ret = -ENOMEM;
-        if ( dom == 0 ) break;
+
+        if ( dom == 0 ) 
+            break;
+
         pro = (pro+1) % smp_num_cpus;
         p = do_newdomain(dom, pro);
-        if ( p == NULL ) break;
+        if ( p == NULL ) 
+            break;
 
         ret = alloc_new_dom_mem(p, op.u.newdomain.memory_kb);
-        if ( ret != 0 ) break;
+        if ( ret != 0 ) 
+        {
+            __kill_domain(p);
+            break;
+        }
 
         build_page_list(p);
         
index ab311f804e47c6425e644e80e7027e02a0267e06..14fcf8eaec9897a5c0cb6484cf06c3f1877d58cb 100644 (file)
@@ -37,7 +37,7 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu)
 
     retval = -ENOMEM;
     p = alloc_task_struct();
-    if (!p) goto newdomain_out;
+    if ( p == NULL ) return NULL;
     memset(p, 0, sizeof(*p));
 
     atomic_set(&p->refcnt, 1);
@@ -75,10 +75,10 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu)
     SET_LINKS(p);
     write_unlock_irqrestore(&tasklist_lock, flags);
 
- newdomain_out:
     return(p);
 }
 
+
 /* Get a pointer to the specified domain.  Consider replacing this
  * with a hash lookup later.
  *
@@ -110,33 +110,45 @@ void kill_domain_with_errmsg(const char *err)
 }
 
 
-/* Kill the currently executing domain. */
-void kill_domain(void)
+void __kill_domain(struct task_struct *p)
 {
     struct list_head *ent;
     net_vif_t *vif;
 
-    if ( current->domain == 0 )
+    if ( p->domain == 0 )
     {
         extern void machine_restart(char *);
         printk("Domain 0 killed: rebooting machine!\n");
         machine_restart(0);
     }
 
-    printk("Killing domain %d\n", current->domain);
+    printk("Killing domain %d\n", p->domain);
 
-    sched_rem_domain(current);
+    sched_rem_domain(p);
 
-    unlink_blkdev_info(current);
+    unlink_blkdev_info(p);
 
-    while ( (ent = current->net_vifs.next) != &current->net_vifs )
+    while ( (ent = p->net_vifs.next) != &p->net_vifs )
     {
         vif = list_entry(ent, net_vif_t, dom_list);
         unlink_net_vif(vif);
     }    
-    
-    schedule();
-    BUG(); /* never get here */
+
+    if ( p == current )
+    {
+        schedule();
+        BUG(); /* never get here */
+    }
+    else
+    {
+        free_task_struct(p);
+    }
+}
+
+
+void kill_domain(void)
+{
+    __kill_domain(current);
 }
 
 
@@ -148,7 +160,11 @@ long kill_other_domain(unsigned int dom, int force)
     p = find_domain_by_id(dom);
     if ( p == NULL ) return -ESRCH;
 
-    if ( force )
+    if ( p->state == TASK_SUSPENDED )
+    {
+        __kill_domain(p);
+    }
+    else if ( force )
     {
         cpu_mask = mark_hyp_event(p, _HYP_EVENT_DIE);
         hyp_event_notify(cpu_mask);
index 117af485c6dab511c244b148bb44a6a5b42bf038..303dba32bad6740145d5dd200784eebdcf18f5a4 100644 (file)
@@ -107,7 +107,7 @@ static inline int __task_on_runqueue(struct task_struct *p)
 ******************************************************************************/
 void sched_add_domain(struct task_struct *p) 
 {
-    p->state       = TASK_UNINTERRUPTIBLE;
+    p->state       = TASK_SUSPENDED;
     p->mcu_advance = 10;
 
     if (p->domain == IDLE_DOMAIN_ID) {
index df63cfafacf2d47f30fb27439b78efeadaa4f86a..5534ee45f364f80c25f98c85259c44ed7203fa05 100644 (file)
@@ -163,7 +163,7 @@ struct task_struct {
  * TASK_UNINTERRUPTIBLE: Domain is blocked but may not be woken up by an
  *                       arbitrary event or timer.
  * TASK_WAIT:            Domains CPU allocation expired.
- * TASK_STOPPED:         not really used in Xen
+ * TASK_SUSPENDED:       Domain is in supsended state (eg. start of day)
  * TASK_DYING:           Domain is about to cross over to the land of the dead.
  */
 
@@ -171,8 +171,8 @@ struct task_struct {
 #define TASK_INTERRUPTIBLE      1
 #define TASK_UNINTERRUPTIBLE    2
 #define TASK_WAIT               4
+#define TASK_SUSPENDED          8
 #define TASK_DYING              16
-/* #define TASK_STOPPED            8  not really used */
 
 #define SCHED_YIELD             0x10
 
@@ -219,6 +219,7 @@ extern int final_setup_guestos(struct task_struct *p, dom_meminfo_t *);
 
 struct task_struct *find_domain_by_id(unsigned int dom);
 extern void release_task(struct task_struct *);
+extern void __kill_domain(struct task_struct *p);
 extern void kill_domain(void);
 extern void kill_domain_with_errmsg(const char *err);
 extern long kill_other_domain(unsigned int dom, int force);